Promise
的 then()
和 catch()
vs. async
/ await
的 try-catch
若用 Promise
的 then()
可能會像這樣寫:
// 模擬發 API,但只會成功 (fulfilled),回傳的資料為 "OK"
function fakeFetch(url) {
return Promise.resolve('OK');
}
function asyncFunc() {
return fakeFetch().then(value => {
console.log(value);
});
}
asyncFunc();
// "OK"
若改用 async
/ await
的寫法:
// 模擬發 API,但只會成功 (fulfilled),回傳的資料為 "OK"
async function fakeFetch() {
return 'OK';
}
async function asyncFunc() {
const result = await fakeFetch();
console.log(result);
}
asyncFunc();
// "OK" 或 "Oops"
若用 Promise
的 then()
的 catch()
,可能會像這樣寫:
function asyncFunc() {
return fakeFetch()
.then(result1 => {
console.log(result1);
return fakeFetch();
})
.then(result2 => {
console.log(result2);
});
}
若改用 async
/ await
就能使用 try-catch
的寫法:
async function asyncFunc() {
const result1 = await fakeFetch();
console.log(result1);
const result2 = await fetchUser();
console.log(result2);
}
可以看到若要按順序處理多個非同步,就會非常麻煩,需要在 then()
的 callback 內寫另一個非同步的處理,若是用 async
/ await
就會很像同步的寫法。
常見的用法是使用 Promise.all()
,可同時處理多個非同步,但必須所有傳入的值都是 fulfilled 才會讓 Promise.all()
回傳的 promise fulfilled,否則會 rejected。
若用 Promise
的 then()
的 catch()
,可能會像這樣寫:
function asyncFunc() {
return Promise.all([
fakeFetch(),
fakeFetch()
])
.then(([result1, result2]) => {
console.log(result1);
console.log(result2);
});
}
若改用 async
/ await
就能使用 try-catch
的寫法:
async function asyncFunc() {
const [result1, result2] = await Promise.all([
fakeFetch(),
fakeFetch()
]);
console.log(result1);
console.log(result2);
}
若用 Promise
的 catch()
可能會像這樣寫:
// 模擬發 API,但只會回傳 "OK"
function fakeFetch(url) {
return Promise.reject(new Error('Oops'));
}
function asyncFunc() {
return fakeFetch()
.then(value => {
console.log(value);
})
.catch(error => {
console.log(error.message);
});
}
asyncFunc();
// "Oops"
若改用 async
/ await
就能使用 try-catch
的寫法:
// 模擬發 API,但只會成功 (rejected),錯誤訊息為 "Oops"
async function fakeFetch() {
throw new Error('Oops');
}
async function asyncFunc() {
try {
const result = await fakeFetch();
console.log(result);
} catch (error) {
console.log(error.message);
}
}
asyncFunc();
// "Oops"
若用 Promise
的 then()
的 catch()
,可能會像這樣寫:
function asyncFunc() {
return fakeFetch()
.then(result1 => {
console.log(result1);
return fakeFetch();
})
.then(result2 => {
console.log(result2);
})
.catch(error => {
console.log(error.message);
});
}
若改用 async
/ await
就能使用 try-catch
的寫法:
async function asyncFunc() {
try {
const result1 = await fakeFetch();
console.log(result1);
const result2 = await fetchUser();
console.log(result2);
} catch (error) {
console.log(error.message);
}
}
上面的處理方式是每個非同步都由同一個 catch
來接收錯誤,若想分別處理錯誤,可以用 catch()
來處理:
async function asyncFunc() {
const result1 = await fakeFetch()
.catch(error => {
console.log(error.message);
});
console.log(result1);
const result2 = await fakeFetch()
.catch(error => {
console.log(error.message);
});
console.log(result2);
}
若用 Promise
的 then()
的 catch()
,可能會像這樣寫:
function asyncFunc() {
return Promise.all([
fakeFetch(),
fakeFetch()
])
.then(([result1, result2]) => {
console.log(result1);
console.log(result2);
})
.catch(error => {
console.log(error.message);
});
}
若改用 async
/ await
就能使用 try-catch
的寫法:
async function asyncFunc() {
try {
const [result1, result2] = await Promise.all([
fakeFetch(),
fakeFetch()
]);
console.log(result1);
console.log(result2);
} catch (error) {
console.log(error.message);
}
}